using System;
using System.IO;
using System.Text;
using Shinkansen.Core;
using Shinkansen.Support;

namespace Shinkansen.Model
{
    class StaticResource: IStaticResource
    {
        private readonly ResourceInformation _ri;
        private readonly PathResolver _pathResolver;

        /// <summary>
        /// Initializes a new instance of the <see cref="StaticResource"/> class.
        /// </summary>
        /// <param name="ri">The ri.</param>
        public StaticResource (ResourceInformation ri)
        {
            _ri = ri;
            _pathResolver = new PathResolver ();
        }

        /// <summary>
        /// Gets the content.
        /// </summary>
        /// <returns></returns>
        public byte[] GetContent ()
        {
            using (MemoryStream ms = new MemoryStream ())
            {
                foreach (string path in _ri.Paths)
                {
                    string absolutePath = _pathResolver.ToAbsolute (path);
                    string physicalPath = _pathResolver.ToPhysical (absolutePath);

                    if (!File.Exists (physicalPath))
                        throw new FileNotFoundException (string.Format ("File '{0}' is not found.", path));

                    byte[] content = ReadContentAsBinary (physicalPath);
                    ms.Write (content, 0, content.Length);
                }

                return ms.ToArray ();
            }
        }

        /// <summary>
        /// Reads the content as binary.
        /// </summary>
        /// <param name="physicalPath">The physical path.</param>
        /// <returns></returns>
        private byte[] ReadContentAsBinary (string physicalPath)
        {
            byte[] content;

            switch (_ri.ResourceType)
            {
                case ResourceType.Image:
                    content = File.ReadAllBytes (physicalPath);
                    break;

                case ResourceType.Css:
                case ResourceType.JavaScript:
                    content = Encoding.UTF8.GetBytes (File.ReadAllText (physicalPath, Encoding.UTF8));
                    break;

                default:
                    throw new InvalidOperationException (
                                    string.Format ("Minification for resource type '{0}' is not supported.", _ri.ResourceType));            }

            return content;
        }
    }
}